package com.droid.lib.controls.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import com.droid.lib.controls.R;
import com.droid.lib.controls.util.DensityUtil;
import com.droid.lib.controls.util.DragViewUtil;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;

/**
 * 根据svg地图展现到桌面
 */
public class SvgPathView extends View implements TwoFingersGestureDetector.TwoFingersGestureListener {
    private int mintMapColor1;
    private int mintMapColor2;
    private int mintMapColor3;
    private int mintMapColor4;
    private int mintSvgMap;
    private String nameTab1 = "highcharts-point highcharts-color-0 highcharts-name-";
    private String nameTab2 = "highcharts-key-000000";
    private List<PathItem> pathItemList;
    private float mflShowScale = 1.5f;
    private int[] mstrColorArray = new int[]{R.color.color_svg_map_bg1, R.color.color_svg_map_bg2, R.color.color_svg_map_bg3, R.color.color_svg_map_bg4};
    private int mintWidth;
    private int mintHeight;
    private int mintViewWidth;
    private int mintViewHeight;
    private float translateX = 0f;
    private float translateY = 0f;
    private float rotateDeg = 0f;
    private int mapTextColor;
    private int dataMapSize = 10;
    private View mvTitlePop;
    private boolean enabledSvgPop = true;
    private boolean enabledSvgCircle = true;
    private Bitmap mbtTitlePop;
    private float mintSelectX = -1;
    private float mintSelectY = -1;
    /**
     * 地图点击的画笔
     */
    private Paint mapPaint;
    /**
     * 文字点击的画笔
     */
    private Paint textPaint;
    /**
     * 圆圈画笔
     */
    private Paint circlePaint;
    /**
     * 地图点击弹出
     */
    private Paint mapPopPaint;
    private TwoFingersGestureDetector mDetector;

    public SvgPathView(Context context) {
        super(context);
    }

    public SvgPathView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
        initPaint();
        initPath(mintSvgMap);
        initTouch();
    }

    public SvgPathView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
        initPaint();
        initPath(mintSvgMap);
        initTouch();
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SvgPathView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
        initPaint();
        initPath(mintSvgMap);
        initTouch();
    }

    private void initTouch() {
        mDetector = new TwoFingersGestureDetector();
        mDetector.setTwoFingersGestureListener(this);
    }

    private void init(Context context, @Nullable AttributeSet attrs) {
        final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.SvgPathView);
        mintSvgMap = attributes.getInteger(R.styleable.SvgPathView_pathAddress, R.raw.china_path);
        mintMapColor1 = attributes.getResourceId(R.styleable.SvgPathView_pathColor1, R.color.color_svg_map_bg1);
        mintMapColor2 = attributes.getResourceId(R.styleable.SvgPathView_pathColor2, R.color.color_svg_map_bg2);
        mintMapColor3 = attributes.getResourceId(R.styleable.SvgPathView_pathColor3, R.color.color_svg_map_bg3);
        mintMapColor4 = attributes.getResourceId(R.styleable.SvgPathView_pathColor4, R.color.color_svg_map_bg4);
        mflShowScale = attributes.getFloat(R.styleable.SvgPathView_pathShowScale, (float) 2);
        mapTextColor = attributes.getColor(R.styleable.SvgPathView_mapTextColor, Color.parseColor("#FFFFFFFF"));
        dataMapSize = attributes.getDimensionPixelSize(R.styleable.SvgPathView_mapTextSize, 10);
        enabledSvgPop = attributes.getBoolean(R.styleable.SvgPathView_enabledSvgPop, true);
        enabledSvgCircle = attributes.getBoolean(R.styleable.SvgPathView_enabledSvgCircle, true);
        mstrColorArray = new int[]{mintMapColor1, mintMapColor2, mintMapColor3, mintMapColor4};

        DisplayMetrics dm = new DisplayMetrics();
        WindowManager wm = (WindowManager) getContext()
                .getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(dm);
        mintWidth = dm.widthPixels;
        mintHeight = dm.heightPixels;
        setTranslationY(translateY=mintHeight/2);
        setTranslationX(translateX=mintWidth/2);
        setScaleX(2.2f);
        setScaleY(2.2f);
    }

    public void initPaint() {
        if (mapPaint == null) {
            mapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        } else {
            mapPaint.clearShadowLayer();
        }
        mapPaint.setAntiAlias(true);
        mapPaint.setStyle(Paint.Style.FILL);
        mapPaint.setStrokeWidth(1f);
        mapPaint.setDither(true);
        if (textPaint == null) {
            textPaint = new TextPaint();
        } else {
            textPaint.clearShadowLayer();
        }
        textPaint.setTextSize(dataMapSize);
        textPaint.setColor(mapTextColor);
        textPaint.setAntiAlias(true);
        textPaint.setDither(true);
//        textPaint.setStrokeWidth(0.5f);
        textPaint.setStyle(Paint.Style.STROKE);
        if (circlePaint == null) {
            circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        } else {
            circlePaint.clearShadowLayer();
        }
        circlePaint.setAntiAlias(true);
        circlePaint.setDither(true);
        if (mapPopPaint == null) {
            mapPopPaint = new Paint();
        } else {
            mapPopPaint.clearShadowLayer();
        }
        mapPopPaint.setStyle(Paint.Style.FILL);
        mapPopPaint.setAntiAlias(true);
    }

    public void initPath(int svgMap) {
        mintSvgMap = svgMap;
        //数显拿不到资源文件流
        try {
            InputStream is = getResources().openRawResource(svgMap);
            NodeList pathList = DragViewUtil.getElementFromPath(is).getElementsByTagName("path");
            if (pathItemList == null) {
                pathItemList = new ArrayList<>();
            } else {
                pathItemList.clear();
            }
            float left = -1;
            float top = -1;
            float right = -1;
            float bottom = -1;
            StringBuffer stringBuffer=new StringBuffer();
            for (int i = 0; i < pathList.getLength(); i++) {
                Element itemElement = (Element) pathList.item(i);
                String pathData = itemElement.getAttribute("d");
                String provinceName = itemElement.getAttribute("class");

                if (provinceName.contains(nameTab2)) {
                    continue;
                }
                if (provinceName.contains(nameTab1)) {
                    provinceName = provinceName.substring(nameTab1.length(), provinceName.length());
                }
                stringBuffer.append("[{"+i+"="+provinceName+"}],");
//                SvgPathToAndroidPath lParser = new SvgPathToAndroidPath();
//                lParser.setScale(mflShowScale);
//                Path path=lParser.parser(pathData);
                Path path = PathParser.createPathFromPathData(pathData);
                PathItem pathItem = new PathItem();
                pathItem.setMapPath(path);
                pathItem.setMapName(provinceName);
                pathItem.setMapRegion(new MapRegion(path));
                RectF rectf = new RectF();
                mapPaint.setColor(pathItem.getMapColor());
                path.computeBounds(rectf, true);
                left = left == -1 ? rectf.left : Math.min(left, rectf.left);
                top = left == -1 ? rectf.top : Math.min(top, rectf.top);
                right = left == -1 ? rectf.right : Math.max(right, rectf.right);
                bottom = left == -1 ? rectf.bottom : Math.max(bottom, rectf.bottom);
                //生成一个大的矩形
                RectF rectF = new RectF(left, top, right, bottom);
                pathItem.setMapRectF(rectF);
                float widthText = textPaint.measureText(pathItem.getMapName());
                pathItem.getMapPath().computeBounds(rectF, true);
                float x = rectF.centerX() - widthText / 2;
                float y = rectF.centerY() - textPaint.getStrokeWidth();
                pathItem.setTextLocation(new PathItem.Location(x, y));
                pathItem.setCircleLocation(new PathItem.Location(rectF.centerX(), rectF.centerY()));
                pathItem.setMapCircleColor(Color.GREEN);

                pathItemList.add(pathItem);
            }
            Log.e("SvgPathView", stringBuffer.toString());
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.fillInStackTrace();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mDetector.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (pathItemList == null) {
            return;
        }
        for (int i = 0; i < pathItemList.size(); i++) {
            mapPaint.clearShadowLayer();
            PathItem pathItem = pathItemList.get(i);
            mapPaint.setStrokeWidth(0.5f);
            mapPaint.setStyle(Paint.Style.FILL);
            mapPaint.setColor(pathItem.getMapColor());
            canvas.drawPath(pathItem.getMapPath(), mapPaint);
            mapPaint.clearShadowLayer();
            mapPaint.setStrokeWidth(0.5f);
            mapPaint.setColor(Color.WHITE);
            mapPaint.setStyle(Paint.Style.STROKE);
            canvas.drawPath(pathItem.getMapPath(), mapPaint);
        }
        if (enabledSvgCircle) {
            for (int i = 0; i < pathItemList.size(); i++) {
                PathItem pathItem = pathItemList.get(i);
                circlePaint.setColor(pathItem.getMapCircleColor());
                canvas.drawCircle(pathItem.getCircleLocation().getX(), pathItem.getCircleLocation().getY(), pathItem.getDataMapRadius(), circlePaint);// 大圆
            }
        }
        for (int i = 0; i < pathItemList.size(); i++) {
            textPaint.clearShadowLayer();
            PathItem pathItem = pathItemList.get(i);
//            canvas.drawRect(pathItem.getMapRectF(),textPaint);
            canvas.drawText(pathItem.getMapName(), pathItem.getTextLocation().getX(), pathItem.getTextLocation().getY(), textPaint);
        }


        if (enabledSvgPop) {
            drowTitlePop(canvas);
        }
    }

    private void drowTitlePop(Canvas canvas) {
        if (mintSelectX == -1 || mintSelectY == -1) {
            return;
        }
        int viewWidth = getWidth();
        int viewHeight = getHeight();
        int btPopWidth = mbtTitlePop.getWidth();
        int btPopHeight = mbtTitlePop.getHeight();
        float thisW = mintSelectX;
        float thisH = mintSelectY;
        float myLeft;
        float myTop;
        if ((viewWidth - (btPopWidth + thisW)) > 0) {
            myLeft = thisW;
        } else {
            myLeft = thisW - btPopWidth;
        }
        if (viewHeight - (btPopHeight + thisH) > 0) {
            myTop = thisH;
        } else {
            myTop = thisH - btPopHeight;
        }
        mapPopPaint.clearShadowLayer();
        canvas.drawBitmap(mbtTitlePop, myLeft, myTop, mapPopPaint);
    }



    @Override
    public void onDown(float downX, float downY, long downTime) {
        mintViewWidth = getWidth();
        mintHeight = getHeight();
    }

    @Override
    public void onMoved(float deltaMovedX, float deltaMovedY, long deltaMilliseconds) {
        setTranslationX(translateX += deltaMovedX);
        setTranslationY(translateY += deltaMovedY);
    }

    @Override
    public void onRotated(float deltaRotatedDeg, long deltaMilliseconds) {
    }

    @Override
    public void onScaled(float deltaScaledX, float deltaScaledY, float deltaScaledDistance, long deltaMilliseconds) {
        mflShowScale += deltaScaledDistance / getWidth();
        setScaleX(mflShowScale);
        setScaleY(mflShowScale);
    }

    public void notifyDataSetChanged() {
        invalidate();
    }

    @Override
    public void onUp(float upX, float upY, long upTime, float xVelocity, float yVelocity) {
        int l = 0;
        for (int i = 0; i < pathItemList.size(); i++) {
            PathItem pathItem = pathItemList.get(i);
            if (pathItem.getMapRegion().isSelect((int) upX, (int) upY)) {
                l++;
                if (enabledSvgPop) {
                    mintSelectX = upX;
                    mintSelectY = upY;
                    if (onCirclePop != null) {
                        mvTitlePop = onCirclePop.onTitleClick(i, pathItem, upX, upY);
                        if(mvTitlePop==null){
                            throw new RuntimeException("请定义你的View");
                        }
                    } else {
                        mvTitlePop = LayoutInflater.from(getContext()).inflate(R.layout.popup_path_card, null);
                        TextView img = (TextView) mvTitlePop.findViewById(R.id.tv_img);
                        TextView title = (TextView) mvTitlePop.findViewById(R.id.tv_name);
                        TextView value = (TextView) mvTitlePop.findViewById(R.id.tv_value);
                        img.setBackgroundColor(pathItem.getMapColor());
                        title.setText(pathItem.getMapName());
                        value.setText(pathItem.getDataMapRadius() + "");
                    }
                    mbtTitlePop = DensityUtil.getViewBitmap(mvTitlePop);
                }
                if (onSVGSelectedListener != null) {
                    onSVGSelectedListener.onSVGSelected(i, pathItem, upX, upY);
                }

            }
        }
        if (l == 0) {
            mintSelectX = -1;
            mintSelectY = -1;
        }
        invalidate();
    }

    @Override
    public void onCancel() {

    }

    private OnSVGSelectedListener onSVGSelectedListener;

    public interface OnSVGSelectedListener {
        void onSVGSelected(int position, PathItem item, float x, float y);
    }

    public OnSVGSelectedListener getOnSVGSelectedListener() {
        return onSVGSelectedListener;
    }

    public void setOnSVGSelectedListener(OnSVGSelectedListener onSVGSelectedListener) {
        this.onSVGSelectedListener = onSVGSelectedListener;
    }

    public interface OnCirclePop {
        View onTitleClick(int position, PathItem pathItem, float touchX, float touchY);
    }

    OnCirclePop onCirclePop;

    public OnCirclePop getOnCirclePop() {
        return onCirclePop;
    }

    public void setOnCirclePop(OnCirclePop onCirclePop) {
        this.onCirclePop = onCirclePop;
    }

    /**
     * [{0=北京}],[{1=天津}],[{2=河北}],[{3=山西}],[{4=内蒙古}],[{5=辽宁}],[{6=吉林}],[{7=黑龙江}],[{8=上海}],[{9=江苏}],[{10=浙江}],[{11=安徽}],[{12=福建}],[{13=江西}],[{14=山东}],[{15=河南}],[{16=湖北}],[{17=湖南}],[{18=广东}],[{19=广西}],[{20=海南}],[{21=重庆}],[{22=四川}],[{23=贵州}],[{24=云南}],[{25=西藏}],[{26=陕西}],[{27=甘肃}],[{28=青海}],[{29=宁夏}],[{30=新疆}],[{31=台湾}],[{32=香港}],[{33=澳门}]
     * @return
     */
    public List<PathItem> getPathItemList() {
        return pathItemList;
    }

    public void setPathItemList(List<PathItem> pathItemList) {
        this.pathItemList = pathItemList;
    }

    public int getMintSvgMap() {
        return mintSvgMap;
    }

    public void setMintSvgMap(int mintSvgMap) {
        this.mintSvgMap = mintSvgMap;
    }

    public boolean isEnabledSvgPop() {
        return enabledSvgPop;
    }

    public void setEnabledSvgPop(boolean enabledSvgPop) {
        this.enabledSvgPop = enabledSvgPop;
    }

    public boolean isEnabledSvgCircle() {
        return enabledSvgCircle;
    }

    public void setEnabledSvgCircle(boolean enabledSvgCircle) {
        this.enabledSvgCircle = enabledSvgCircle;
    }
}
